{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 载入数据\n",
    "data = np.genfromtxt(\"kmeans.txt\", delimiter=\" \")  # 注意是空格隔开\n",
    "\n",
    "plt.scatter(data[:,0],data[:,1])\n",
    "plt.show()  # 大致推断有4个类，从图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(80, 2)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape  # 80行2列，就是说80个样本，每个样本2个特征"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算距离 ，欧几里得距离\n",
    "def euclDistance(vector1, vector2):  \n",
    "    return np.sqrt(sum((vector2 - vector1)**2))\n",
    "  \n",
    "# 初始化质心\n",
    "def initCentroids(data, k):  \n",
    "    numSamples, dim = data.shape\n",
    "    # k个质心，列数跟样本的列数一样\n",
    "    centroids = np.zeros((k, dim))  \n",
    "    # 随机选出k个质心\n",
    "    for i in range(k):  \n",
    "        # 随机选取一个样本的索引\n",
    "        index = int(np.random.uniform(0, numSamples))  \n",
    "        # 作为初始化的质心\n",
    "        centroids[i, :] = data[index, :]  \n",
    "    return centroids  \n",
    "  \n",
    "# 传入数据集和k的值\n",
    "def kmeans(data, k):  # 定义k-means函数\n",
    "    # 计算样本个数\n",
    "    numSamples = data.shape[0]   \n",
    "    # 样本的属性，第一列保存该样本属于哪个簇，第二列保存该样本跟它所属簇的误差\n",
    "    clusterData = np.array(np.zeros((numSamples, 2)))  # 初始化全为0\n",
    "    # 决定质心是否要改变的变量\n",
    "    clusterChanged = True  # 质心要改变true\n",
    "  \n",
    "    # 初始化质心  \n",
    "    centroids = initCentroids(data, k)  \n",
    "  \n",
    "    while clusterChanged:  \n",
    "        clusterChanged = False  \n",
    "        # 循环每一个样本 \n",
    "        for i in range(numSamples):  \n",
    "            # 最小距离\n",
    "            minDist  = 100000.0  \n",
    "            # 定义样本所属的簇\n",
    "            minIndex = 0  \n",
    "            # 循环计算每一个质心与该样本的距离\n",
    "            for j in range(k):  \n",
    "                # 循环每一个质心和样本，计算距离\n",
    "                distance = euclDistance(centroids[j, :], data[i, :])  \n",
    "                # 如果计算的距离小于最小距离，则更新最小距离\n",
    "                if distance < minDist:  \n",
    "                    minDist  = distance \n",
    "                    # 更新最小距离\n",
    "                    clusterData[i, 1] = minDist\n",
    "                    # 更新样本所属的簇\n",
    "                    minIndex = j  \n",
    "              \n",
    "            # 如果样本的所属的簇发生了变化\n",
    "            if clusterData[i, 0] != minIndex:  \n",
    "                # 质心要重新计算\n",
    "                clusterChanged = True\n",
    "                # 更新样本的簇\n",
    "                clusterData[i, 0] = minIndex\n",
    "  \n",
    "        # 更新4个质心的值\n",
    "        for j in range(k):  \n",
    "            # 获取第j个簇所有的样本所在的索引\n",
    "            cluster_index = np.nonzero(clusterData[:, 0] == j)  # 见下面的说明\n",
    "            # 第j个簇所有的样本点\n",
    "            pointsInCluster = data[cluster_index]  \n",
    "            # 计算质心，算术平均数，质心计算方式：所属簇所有样本的算术平均数\n",
    "            centroids[j, :] = np.mean(pointsInCluster, axis = 0) \n",
    "#         showCluster(data, k, centroids, clusterData)\n",
    " \n",
    "    return centroids, clusterData  # 质心，样本属性\n",
    "  \n",
    "# 显示结果 \n",
    "def showCluster(data, k, centroids, clusterData):  \n",
    "    numSamples, dim = data.shape  \n",
    "    if dim != 2:  \n",
    "        print(\"dimension of your data is not 2!\")  \n",
    "        return 1  \n",
    "  \n",
    "    # 用不同颜色形状来表示各个类别，ob红色圆形\n",
    "    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']  \n",
    "    if k > len(mark):  \n",
    "        print(\"Your k is too large!\")  \n",
    "        return 1  \n",
    "  \n",
    "    # 画样本点  \n",
    "    for i in range(numSamples):  \n",
    "        markIndex = int(clusterData[i, 0])  \n",
    "        plt.plot(data[i, 0], data[i, 1], mark[markIndex])  \n",
    "  \n",
    "    # 用不同颜色形状来表示各个类别\n",
    "    mark = ['*r', '*b', '*g', '*k', '^b', '+b', 'sb', 'db', '<b', 'pb']  \n",
    "    # 画质心点 \n",
    "    for i in range(k):  \n",
    "        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 20)  \n",
    "  \n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False,  True, False, False, False, False,  True,\n",
       "        True,  True, False, False])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 测试单个的意思\n",
    "test = np.array([1,2,3,0,1,1,2,2,0,0,0,3,2])\n",
    "test == 0  # 作比较。测试true和false\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([ 3,  8,  9, 10], dtype=int64),)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.nonzero(test == 0)   # 等与0的元素所在的索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cluster complete!\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 设置k值，就是设置4个类\n",
    "k = 4  \n",
    "# centroids 簇的中心点 \n",
    "# cluster Data样本的属性，第一列保存该样本属于哪个簇，第二列保存该样本跟它所属簇的误差\n",
    "centroids, clusterData = kmeans(data, k)  # 调用k-means\n",
    "if np.isnan(centroids).any():\n",
    "    print('Error')\n",
    "else:\n",
    "    print('cluster complete!')   \n",
    "    # 显示结果\n",
    "showCluster(data, k, centroids, clusterData)    # 在个别情况下，由于质心取值的随机性，导致分为3个或者不合理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-3.53973889, -2.89384326],\n",
       "       [-2.46154315,  2.78737555],\n",
       "       [ 2.65077367, -2.79019029],\n",
       "       [ 2.6265299 ,  3.10868015]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "centroids"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 做预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1],\n",
       "       [0, 1],\n",
       "       [0, 1],\n",
       "       [0, 1]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 做预测\n",
    "x_test = [0,1]\n",
    "np.tile(x_test,(k,1))  # 复制次数，行复制k次，列复制1次"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 3.53973889,  3.89384326],\n",
       "       [ 2.46154315, -1.78737555],\n",
       "       [-2.65077367,  3.79019029],\n",
       "       [-2.6265299 , -2.10868015]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差\n",
    "np.tile(x_test,(k,1))-centroids"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[12.52975144, 15.16201536],\n",
       "       [ 6.05919468,  3.19471136],\n",
       "       [ 7.02660103, 14.3655424 ],\n",
       "       [ 6.89865932,  4.44653198]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差平方\n",
    "(np.tile(x_test,(k,1))-centroids)**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([27.6917668 ,  9.25390604, 21.39214343, 11.34519129])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差平方和\n",
    "((np.tile(x_test,(k,1))-centroids)**2).sum(axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最小值所在的索引号\n",
    "np.argmin(((np.tile(x_test,(k,1))-centroids)**2).sum(axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict(datas):\n",
    "    return np.array([np.argmin(((np.tile(data,(k,1))-centroids)**2).sum(axis=1)) for data in datas])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 画出簇的作用区域"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 获取数据值所在的范围\n",
    "x_min, x_max = data[:, 0].min() - 1, data[:, 0].max() + 1\n",
    "y_min, y_max = data[:, 1].min() - 1, data[:, 1].max() + 1\n",
    "\n",
    "# 生成网格矩阵\n",
    "xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),\n",
    "                     np.arange(y_min, y_max, 0.02))\n",
    "\n",
    "z = predict(np.c_[xx.ravel(), yy.ravel()])# ravel与flatten类似，多维数据转一维。flatten不会改变原始数据，ravel会改变原始数据\n",
    "z = z.reshape(xx.shape)\n",
    "# 等高线图\n",
    "cs = plt.contourf(xx, yy, z)\n",
    "# 显示结果\n",
    "showCluster(data, k, centroids, clusterData)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
